﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Xml.XPath;
using System.Xml.Linq;
using System.Text;
using System.Windows.Forms;

namespace UCL.Forms.Components
{
    /// <summary>
    /// 中国省市区选择控件
    /// </summary>
    /// <remarks>2014-3-14 by sutroon</remarks>
    public partial class ucCnRegion : UserControl
    {
        /// <summary>
        /// 获取或设置下拉框控件改变的委托方法
        /// <para>参数：name,tag</para>
        /// </summary>
        public Action<string, string> SelectedIndexChangedHandler { get; set; }

        /// <summary>
        /// 获取或设置设置文本的委托方法
        /// <para>参数：省市区街道社区的组合字符串，以空格隔开</para>
        /// </summary>
        public Action<string> SetTextHandler { get; set; }

        /// <summary>
        /// 获取或设置下拉框无数据或默认第一项文本,默认是[请选择...]
        /// </summary>
        public string DefaultText { get; set; }

        /// <summary>
        /// 获取或设置默认省份的名称
        /// </summary>
        public string DefaultProvince { get; set; }

        /// <summary>
        /// 获取或设置保留的文本框字符串
        /// </summary>
        public string KeepText { get; set; }

        /// <summary>
        /// 获取或设置节点间值的分隔符号,默认是空格[ ]
        /// </summary>
        public string Splitor { get; set; }

        /// <summary>
        /// 获取或设置街道下拉框是否显示
        /// </summary>
        public bool StreetVisible { get { return cbbStreet.Visible; } set { cbbStreet.Visible = value; ResizeControlWidth(); } }

        /// <summary>
        /// 获取或设置社区下拉框是否显示
        /// </summary>
        public bool CommunityVisible { get { return cbbCommunity.Visible; } set { cbbCommunity.Visible = value; ResizeControlWidth(); } }

        /// <summary>
        /// 获取或设置应用按钮是否显示
        /// </summary>
        public bool ButtonVisible { get { return btnApply.Visible; } set { btnApply.Visible = value; ResizeControlWidth(); } }

        /// <summary>
        /// 获取或设置省份下拉框的宽度
        /// </summary>
        public int ProvinceWidth { get { return cbbProvince.Width; } set { cbbProvince.Width = value; ResizeControlWidth(); } }

        /// <summary>
        /// 获取或设置城市下拉框的宽度
        /// </summary>
        public int CityWidth { get { return cbbCity.Width; } set { cbbCity.Width = value; ResizeControlWidth(); } }

        /// <summary>
        /// 获取或设置地区下拉框的宽度
        /// </summary>
        public int AreaWidth { get { return cbbArea.Width; } set { cbbArea.Width = value; ResizeControlWidth(); } }

        /// <summary>
        /// 获取或设置街道下拉框的宽度
        /// </summary>
        public int StreetWidth { get { return cbbStreet.Width; } set { cbbStreet.Width = value; ResizeControlWidth(); } }

        /// <summary>
        /// 获取或设置社区下拉框的宽度
        /// </summary>
        public int CommunityWidth { get { return cbbCommunity.Width; } set { cbbCommunity.Width = value; ResizeControlWidth(); } }

        private string tableName = "tCnRegion";
        private XElement doc, nProvince, nCity, nArea, nStreet, nCommunity;
        public ucCnRegion()
        {
            InitializeComponent();
            cbbProvince.SelectedIndexChanged += new EventHandler(cbbProvince_SelectedIndexChanged);
            cbbCity.SelectedIndexChanged += new EventHandler(cbbCity_SelectedIndexChanged);
            cbbArea.SelectedIndexChanged += new EventHandler(cbbArea_SelectedIndexChanged);
            cbbStreet.SelectedIndexChanged += new EventHandler(cbbStreet_SelectedIndexChanged);
            cbbCommunity.SelectedIndexChanged += new EventHandler(cbbCommunity_SelectedIndexChanged);
            DefaultText = "请选择...";
            DefaultProvince = "福建省";
            KeepText = string.Empty;
            Splitor = " ";
        }

        int width;
        // 重设控件宽度
        private void ResizeControlWidth()
        {
            width = cbbProvince.Width + cbbCity.Width + cbbArea.Width;
            if (cbbStreet.Visible) width += cbbStreet.Width;
            if (cbbCommunity.Visible) width += cbbCommunity.Width;
            if (btnApply.Visible) width += btnApply.Width;
            this.Width = width;
        }
        
        /// <summary>
        /// 控件初始化
        /// </summary>
        public void control_init()
        {
            try
            {
                doc = XElement.Parse(ComRes.region_cn);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }
            cbbProvince.DataSource = BindData("", "PROVINCE");
            if (!string.IsNullOrEmpty(DefaultProvince)) this.SetValue(DefaultProvince);

        }


        private void cbbProvince_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cbbProvince.SelectedItem == null) return;
            nProvince = doc.XPathSelectElement(string.Format("province[@name='{0}']", cbbProvince.SelectedItem));
            if (nProvince == null) return;
            cbbCity.DataSource = BindData(cbbProvince.SelectedItem.ToString(), "CITY");
            if (SelectedIndexChangedHandler != null) SelectedIndexChangedHandler(cbbProvince.SelectedItem.ToString(), "PROVINCE");
            if (SetTextHandler != null) SetTextHandler(GetText());
        }

        private void cbbCity_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cbbCity.SelectedItem == null || nProvince == null) return;
            nCity = nProvince.XPathSelectElement(string.Format("city[@name='{0}']", cbbCity.SelectedItem));
            if (nCity == null) return;
            cbbArea.DataSource = BindData(cbbCity.SelectedItem.ToString(), "AREA");
            if (SelectedIndexChangedHandler != null) SelectedIndexChangedHandler(cbbCity.SelectedItem.ToString(), "CITY");
            if (SetTextHandler != null) SetTextHandler(GetText());
        }

        private void cbbArea_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cbbArea.SelectedItem == null || nCity == null) return;
            nArea = nCity.XPathSelectElement(string.Format("area[@name='{0}']", cbbArea.SelectedItem));
            if (nArea == null) return;
            cbbStreet.DataSource = BindData(cbbArea.SelectedItem.ToString(), "STREET");
            if (SelectedIndexChangedHandler != null) SelectedIndexChangedHandler(cbbArea.SelectedItem.ToString(), "AREA");
            if (SetTextHandler != null) SetTextHandler(GetText());
        }

        private void cbbStreet_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cbbStreet.SelectedItem == null || nArea == null) return;
            nStreet = nArea.XPathSelectElement(string.Format("street[@name='{0}']", cbbStreet.SelectedItem));
            if (nStreet == null) return;
            cbbCommunity.DataSource = BindData(cbbStreet.SelectedItem.ToString(), "COMMUNITY");
            if (SelectedIndexChangedHandler != null) SelectedIndexChangedHandler(cbbStreet.SelectedItem.ToString(), "STREET");
            if (SetTextHandler != null) SetTextHandler(GetText());
        }

        private void cbbCommunity_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cbbCommunity.SelectedItem == null || nStreet == null) return;
            nCommunity = nStreet.XPathSelectElement(string.Format("community[@name='{0}']", cbbCommunity.SelectedItem));
            if (nCommunity == null) return;
            if (SelectedIndexChangedHandler != null) SelectedIndexChangedHandler(cbbCommunity.SelectedItem.ToString(), "COMMUNITY");
            if (SetTextHandler != null) SetTextHandler(GetText());
        }
        public void SetValue(string province = "", string city = "", string area = "", string street = "", string community = "")
        {
            if (!string.IsNullOrEmpty(province)) cbbProvince.SelectedItem = province;
            if (!string.IsNullOrEmpty(city)) cbbCity.SelectedItem = city;
            if (!string.IsNullOrEmpty(area)) cbbArea.SelectedItem = area;
            if (!string.IsNullOrEmpty(street)) cbbStreet.SelectedItem = street;
            if (!string.IsNullOrEmpty(community)) cbbCommunity.SelectedItem = community;
        }

        /// <summary>
        /// 获取当前控件的值
        /// </summary>
        /// <returns></returns>
        public string GetText()
        {
            StringBuilder sb = new StringBuilder();
            if (cbbProvince.SelectedItem != null && cbbProvince.SelectedItem.ToString() != DefaultText) sb.AppendFormat(" {0}", cbbProvince.SelectedItem);
            if (cbbCity.SelectedItem != null && cbbCity.SelectedItem.ToString() != DefaultText) sb.AppendFormat(" {0}", cbbCity.SelectedItem);
            if (cbbArea.SelectedItem != null && cbbArea.SelectedItem.ToString() != DefaultText) sb.AppendFormat(" {0}", cbbArea.SelectedItem);
            if (cbbStreet.SelectedItem != null && cbbStreet.SelectedItem.ToString() != DefaultText) sb.AppendFormat(" {0}", cbbStreet.SelectedItem);
            if (cbbCommunity.SelectedItem != null && cbbCommunity.SelectedItem.ToString() != DefaultText) sb.AppendFormat(" {0}", cbbCommunity.SelectedItem);
            if (!string.IsNullOrEmpty(KeepText)) sb.AppendFormat(" {0}", KeepText);
            return sb.ToString().Trim();
        }

        private IList<string> BindData(string parentName, string tag)
        {
            IList<string> lst = new List<string>();
            IEnumerable<XElement> eles = null;
            switch (tag)
            {
                case "PROVINCE":
                    eles = doc.Elements();
                    break;
                case "CITY":
                    if (nProvince != null) eles = nProvince.Elements();
                    break;
                case "AREA":
                    if (nCity != null) eles = nCity.Elements();
                    break;
                case "STREET":
                    if (nArea != null) eles = nArea.Elements();
                    break;
                case "COMMUNITY":
                    if (nStreet != null) eles = nStreet.Elements();
                    break;
            }
            if (eles == null) return null;
            foreach (XElement n in eles)
            {
                lst.Add(n.Attribute("name").Value);
            }
            return lst;
        }
    }
}
